package com.unicdata.ai.demo_2af.aspect;

import com.unicdata.ai.demo_2af.annotation.EncryptField;
import com.unicdata.ai.demo_2af.common.utils.AesEncryptUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Collection;

/**
 * 加解密切面
 *
 * @author lhn
 * @date 2025/06/26 15:23
 * @since 1.0.0
 **/
@Aspect
@Component
public class SensitiveFieldAspect {

    @Before("execution(* com.unicdata..*.insert*(..)) || execution(* com.unicdata..*.save*(..)) || execution(* com.unicdata..*.update*(..))")
    public void encryptSensitiveFields(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        if (args == null) return;
        for (Object arg : args) {
            processFields(arg, true);
        }
    }

    @AfterReturning(pointcut = "execution(* com.unicdata..*.get*(..)) || execution(* com.unicdata..*.query*(..))", returning = "result")
    public void decryptSensitiveFields(JoinPoint joinPoint, Object result) {
        if (result == null) return;

        if (result instanceof Collection) {
            for (Object item : (Collection<?>) result) {
                processFields(item, false);
            }
        } else {
            processFields(result, false);
        }
    }

    private void processFields(Object target, boolean encrypt) {
        if (target == null) return;
        Class<?> clazz = target.getClass();

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(EncryptField.class)) {
                field.setAccessible(true);
                try {
                    Object val = field.get(target);
                    if (val != null && val instanceof String) {
                        String strVal = (String) val;
                        if (!strVal.trim().isEmpty()) {
                            if (encrypt) {
                                // 如果是加密操作，先检查是否已经是加密状态
                                if (!isEncrypted(strVal)) {
                                    String newVal = AesEncryptUtils.encrypt(strVal);
                                    field.set(target, newVal);
                                }
                            } else {
                                // 如果是解密操作，先检查是否是加密状态
                                if (isEncrypted(strVal)) {
                                    String newVal = AesEncryptUtils.decrypt(strVal);
                                    field.set(target, newVal);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException("敏感字段处理失败: " + field.getName(), e);
                }
            }
        }
    }


    /**
     * 判断字符串是否已经是加密状态
     * 这里的判断逻辑需要根据您的具体加密方式来调整
     */
    private boolean isEncrypted(String value) {
        return value != null && value.startsWith("ENC:");
    }
}